

 /*
 This file '_tooltip' is part of Firebird Integrated Solution 1.0

 Copyright (c) 2015 Lincong

 Contact:  
        Email: lincong1987@gmail.com

        QQ: 159257119
 
 See Usage at http://www.jplatformx.com/firebird

 Create date: 2015-07-14 04:48
 */


 (function ($) {

     var increments = 0;

     function addDescribedBy(elem, id) {
         var describedby = (elem.attr("aria-describedby") || "").split(/\s+/);
         describedby.push(id);
         elem
             .data("ui-tooltip-id", id)
             .attr("aria-describedby", $.trim(describedby.join(" ")));
     }

     function removeDescribedBy(elem) {
         var id = elem.data("ui-tooltip-id"),
             describedby = (elem.attr("aria-describedby") || "").split(/\s+/),
             index = $.inArray(id, describedby);
         if (index !== -1) {
             describedby.splice(index, 1);
         }

         elem.removeData("ui-tooltip-id");
         describedby = $.trim(describedby.join(" "));
         if (describedby) {
             elem.attr("aria-describedby", describedby);
         } else {
             elem.removeAttr("aria-describedby");
         }
     }

     $.widget("ui.tooltip", {
         version: "1.9.2",
         options: {
             content: function () {
                 return $(this).attr("title");
             },
             hide: true,
             // Disabled elements have inconsistent behavior across browsers (#8661)
             items: "[title]:not([disabled])",
             position: {
                 my: "left top+15",
                 at: "left bottom",
                 collision: "flipfit flip"
             },
             show: true,
             tooltipClass: null,
             track: false,

             // callbacks
             close: null,
             open: null
         },

         _create: function () {
             this._on({
                 mouseover: "open",
                 focusin: "open"
             });

             // IDs of generated tooltips, needed for destroy
             this.tooltips = {};
             // IDs of parent tooltips where we removed the title attribute
             this.parents = {};

             if (this.options.disabled) {
                 this._disable();
             }
         },

         _setOption: function (key, value) {
             var that = this;

             if (key === "disabled") {
                 this[value ? "_disable" : "_enable"]();
                 this.options[key] = value;
                 // disable element style changes
                 return;
             }

             this._super(key, value);

             if (key === "content") {
                 $.each(this.tooltips, function (id, element) {
                     that._updateContent(element);
                 });
             }
         },

         _disable: function () {
             var that = this;

             // close open tooltips
             $.each(this.tooltips, function (id, element) {
                 var event = $.Event("blur");
                 event.target = event.currentTarget = element[0];
                 that.close(event, true);
             });

             // remove title attributes to prevent native tooltips
             this.element.find(this.options.items).andSelf().each(function () {
                 var element = $(this);
                 if (element.is("[title]")) {
                     element
                         .data("ui-tooltip-title", element.attr("title"))
                         .attr("title", "");
                 }
             });
         },

         _enable: function () {
             // restore title attributes
             this.element.find(this.options.items).andSelf().each(function () {
                 var element = $(this);
                 if (element.data("ui-tooltip-title")) {
                     element.attr("title", element.data("ui-tooltip-title"));
                 }
             });
         },

         open: function (event) {
             var that = this,
                 target = $(event ? event.target : this.element)
                     // we need closest here due to mouseover bubbling,
                     // but always pointing at the same event target
                     .closest(this.options.items);

             // No element to show a tooltip for or the tooltip is already open
             if (!target.length || target.data("ui-tooltip-id")) {
                 return;
             }

             if (target.attr("title")) {
                 target.data("ui-tooltip-title", target.attr("title"));
             }

             target.data("ui-tooltip-open", true);

             // kill parent tooltips, custom or native, for hover
             if (event && event.type === "mouseover") {
                 target.parents().each(function () {
                     var parent = $(this),
                         blurEvent;
                     if (parent.data("ui-tooltip-open")) {
                         blurEvent = $.Event("blur");
                         blurEvent.target = blurEvent.currentTarget = this;
                         that.close(blurEvent, true);
                     }
                     if (parent.attr("title")) {
                         parent.uniqueId();
                         that.parents[this.id] = {
                             element: this,
                             title: parent.attr("title")
                         };
                         parent.attr("title", "");
                     }
                 });
             }

             this._updateContent(target, event);
         },

         _updateContent: function (target, event) {
             var content,
                 contentOption = this.options.content,
                 that = this,
                 eventType = event ? event.type : null;

             if (typeof contentOption === "string") {
                 return this._open(event, target, contentOption);
             }

             content = contentOption.call(target[0], function (response) {
                 // ignore async response if tooltip was closed already
                 if (!target.data("ui-tooltip-open")) {
                     return;
                 }
                 // IE may instantly serve a cached response for ajax requests
                 // delay this call to _open so the other call to _open runs first
                 that._delay(function () {
                     // jQuery creates a special event for focusin when it doesn't
                     // exist natively. To improve performance, the native event
                     // object is reused and the type is changed. Therefore, we can't
                     // rely on the type being correct after the event finished
                     // bubbling, so we set it back to the previous value. (#8740)
                     if (event) {
                         event.type = eventType;
                     }
                     this._open(event, target, response);
                 });
             });
             if (content) {
                 this._open(event, target, content);
             }
         },

         _open: function (event, target, content) {
             var tooltip, events, delayedShow,
                 positionOption = $.extend({}, this.options.position);

             if (!content) {
                 return;
             }

             // Content can be updated multiple times. If the tooltip already
             // exists, then just update the content and bail.
             tooltip = this._find(target);
             if (tooltip.length) {
                 tooltip.find(".ui-tooltip-content").html(content);
                 return;
             }

             // if we have a title, clear it to prevent the native tooltip
             // we have to check first to avoid defining a title if none exists
             // (we don't want to cause an element to start matching [title])
             //
             // We use removeAttr only for key events, to allow IE to export the correct
             // accessible attributes. For mouse events, set to empty string to avoid
             // native tooltip showing up (happens only when removing inside mouseover).
             if (target.is("[title]")) {
                 if (event && event.type === "mouseover") {
                     target.attr("title", "");
                 } else {
                     target.removeAttr("title");
                 }
             }

             tooltip = this._tooltip(target);
             addDescribedBy(target, tooltip.attr("id"));
             tooltip.find(".ui-tooltip-content").html(content);

             function position(event) {
                 positionOption.of = event;
                 if (tooltip.is(":hidden")) {
                     return;
                 }
                 tooltip.position(positionOption);
             }

             if (this.options.track && event && /^mouse/.test(event.type)) {
                 this._on(this.document, {
                     mousemove: position
                 });
                 // trigger once to override element-relative positioning
                 position(event);
             } else {
                 tooltip.position($.extend({
                     of: target
                 }, this.options.position));
             }

             tooltip.hide();

             this._show(tooltip, this.options.show);
             // Handle tracking tooltips that are shown with a delay (#8644). As soon
             // as the tooltip is visible, position the tooltip using the most recent
             // event.
             if (this.options.show && this.options.show.delay) {
                 delayedShow = setInterval(function () {
                     if (tooltip.is(":visible")) {
                         position(positionOption.of);
                         clearInterval(delayedShow);
                     }
                 }, $.fx.interval);
             }

             this._trigger("open", event, {tooltip: tooltip});

             events = {
                 keyup: function (event) {
                     if (event.keyCode === $.ui.keyCode.ESCAPE) {
                         var fakeEvent = $.Event(event);
                         fakeEvent.currentTarget = target[0];
                         this.close(fakeEvent, true);
                     }
                 },
                 remove: function () {
                     this._removeTooltip(tooltip);
                 }
             };
             if (!event || event.type === "mouseover") {
                 events.mouseleave = "close";
             }
             if (!event || event.type === "focusin") {
                 events.focusout = "close";
             }
             this._on(true, target, events);
         },

         close: function (event) {
             var that = this,
                 target = $(event ? event.currentTarget : this.element),
                 tooltip = this._find(target);

             // disabling closes the tooltip, so we need to track when we're closing
             // to avoid an infinite loop in case the tooltip becomes disabled on close
             if (this.closing) {
                 return;
             }

             // only set title if we had one before (see comment in _open())
             if (target.data("ui-tooltip-title")) {
                 target.attr("title", target.data("ui-tooltip-title"));
             }

             removeDescribedBy(target);

             tooltip.stop(true);
             this._hide(tooltip, this.options.hide, function () {
                 that._removeTooltip($(this));
             });

             target.removeData("ui-tooltip-open");
             this._off(target, "mouseleave focusout keyup");
             // Remove 'remove' binding only on delegated targets
             if (target[0] !== this.element[0]) {
                 this._off(target, "remove");
             }
             this._off(this.document, "mousemove");

             if (event && event.type === "mouseleave") {
                 $.each(this.parents, function (id, parent) {
                     $(parent.element).attr("title", parent.title);
                     delete that.parents[id];
                 });
             }

             this.closing = true;
             this._trigger("close", event, {tooltip: tooltip});
             this.closing = false;
         },

         _tooltip: function (element) {
             var id = "ui-tooltip-" + increments++,
                 tooltip = $("<div>")
                     .attr({
                         id: id,
                         role: "tooltip"
                     })
                     .addClass("ui-tooltip ui-widget ui-corner-all ui-widget-content " +
                     ( this.options.tooltipClass || "" ));
             $("<div>")
                 .addClass("ui-tooltip-content")
                 .appendTo(tooltip);
             tooltip.appendTo(this.document[0].body);
             if ($.fn.bgiframe) {
                 tooltip.bgiframe();
             }
             this.tooltips[id] = element;
             return tooltip;
         },

         _find: function (target) {
             var id = target.data("ui-tooltip-id");
             return id ? $("#" + id) : $();
         },

         _removeTooltip: function (tooltip) {
             tooltip.remove();
             delete this.tooltips[tooltip.attr("id")];
         },

         _destroy: function () {
             var that = this;

             // close open tooltips
             $.each(this.tooltips, function (id, element) {
                 // Delegate to close method to handle common cleanup
                 var event = $.Event("blur");
                 event.target = event.currentTarget = element[0];
                 that.close(event, true);

                 // Remove immediately; destroying an open tooltip doesn't use the
                 // hide animation
                 $("#" + id).remove();

                 // Restore the title
                 if (element.data("ui-tooltip-title")) {
                     element.attr("title", element.data("ui-tooltip-title"));
                     element.removeData("ui-tooltip-title");
                 }
             });
         }
     });

 }(jQuery) );